﻿#region zh-CHS 2006 - 2007 DemoSoft 团队 | en 2006 - 2007 DemoSoft Team

//     NOTES
// ---------------
//
// This file is a part of the G.O.S.E(Game Online Server Engine) for .NET.
//
//                 2006-2007 DemoSoft Team
//
//
// First Version : by H.Q.Cai - mailto:caihuanqing@hotmail.com

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

#region zh-CHS 包含名字空间 | en Include namespace
using System;
using System.IO;
using System.Text;
using System.CodeDom;
using Microsoft.CSharp;
using System.Reflection;
using System.Collections;
using Microsoft.VisualBasic;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Security.Cryptography;
using Demo_G.O.S.E.ServerEngine.Server;
using Demo_G.O.S.E.ServerEngine.Common;
#endregion

namespace Demo_G.O.S.E.ServerEngine.BuildScripts
{
    /// <summary>
    /// 实时编译脚本(C#或VB-源码)的类
    /// </summary>
    public class ScriptCompiler
    {
        #region zh-CHS 私有静态成员变量 | en Private Static Member Variables
        /// <summary>
        /// 额外附加的引用集的名称的列表
        /// </summary>
        private static List<string> s_AdditionalReferences          = new List<string>();
        /// <summary>
        /// 编译后主程序所引用集的缓存类型申明的集合
        /// </summary>
        private static Dictionary<Assembly, TypeCache> s_TypeCaches = new Dictionary<Assembly, TypeCache>();
        /// <summary>
        /// 空的缓存类型申明
        /// </summary>
        private static TypeCache s_NullCache                        = new TypeCache( null );
        #endregion

        #region zh-CHS 静态属性 | en Static Properties
        #region zh-CHS 私有静态成员变量 | en Private Static Member Variables
        /// <summary>
        /// 编译后主程序所引用集的数组
        /// </summary>
        private static Assembly[] s_Assemblies = null;
        #endregion
        /// <summary>
        /// 给出编译后的引用集的数组
        /// </summary>
        public static Assembly[] Assemblies
        {
            get { return s_Assemblies; }
            set { s_Assemblies = value; }
        }
        #endregion

        #region zh-CHS 静态方法 | en Static Method
        /// <summary>
        /// 给出所有附加的引用集的名称列表
        /// </summary>
        public static string[] GetReferenceAssemblies()
        {
            List<string> l_List = new List<string>();

            string l_strPath = Path.Combine( BaseServer.BaseDirectory, "../Scripts/Assemblies.config" );

            if ( File.Exists( l_strPath ) )
            {
                using ( StreamReader l_StreamReader = new StreamReader( l_strPath ) )
                {
                    string l_strLine;

                    while ( ( l_strLine = l_StreamReader.ReadLine() ) != null )
                    {
                        if ( l_strLine.Length > 0 &&
                                ( l_strLine.StartsWith( "#" ) == false ||
                                  l_strLine.StartsWith( "//" ) == false ||
                                  l_strLine.StartsWith( ";" ) == false ) )
                            l_List.Add( l_strLine );
                    }
                }
            }

            l_List.Add( BaseServer.ExePath );

            l_List.AddRange( s_AdditionalReferences );

            return l_List.ToArray();
        }

        /// <summary>
        /// 编译C#的源码
        /// </summary>
        public static bool CompileCSScripts( out Assembly assembly )
        {
            return CompileCSScripts( false, true, out assembly );
        }

        /// <summary>
        /// 编译C#的源码
        /// </summary>
        public static bool CompileCSScripts( bool bDebug, out Assembly assembly )
        {
            return CompileCSScripts( bDebug, true, out assembly );
        }

        /// <summary>
        /// 编译C#的源码
        /// </summary>
        public static bool CompileCSScripts( bool bDebug, bool bCache, out Assembly assembly )
        {
            LOGs.WriteLine( LogMessageType.MSG_INFO, "脚本: 开始编译 C# 脚本..." );
            string[] strFiles = GetScripts( "*.cs" );

            if ( strFiles.Length == 0 )
            {
                if ( bCache && File.Exists( "Scripts/Scripts.CS.dll" ) )
                {
                    assembly = Assembly.LoadFrom( "Scripts/Scripts.CS.dll" );

                    if ( !s_AdditionalReferences.Contains( assembly.Location ) )
                    {
                        s_AdditionalReferences.Add( assembly.Location );
                    }

                    LOGs.WriteLine( LogMessageType.MSG_INFO, "脚本: 完成 C# (读取无任何改变的缓存文件)" );

                    return true;
                }
                else
                {
                    LOGs.WriteLine( LogMessageType.MSG_WARNING, "脚本: 没有找到 C# 的脚本文件!" );
                    assembly = null;
                    return true;
                }
            }

            if ( File.Exists( "Scripts/Scripts.CS.dll" ) )
            {
                if ( bCache && File.Exists( "Scripts/Scripts.CS.hash" ) )
                {
                    try
                    {
                        byte[] byteHashCode = GetHashCode( "Scripts/Scripts.CS.dll", strFiles, bDebug );

                        using ( FileStream l_FileStream = new FileStream( "Scripts/Scripts.CS.hash", FileMode.Open, FileAccess.Read, FileShare.Read ) )
                        {
                            using ( BinaryReader l_BinaryReader = new BinaryReader( l_FileStream ) )
                            {
                                byte[] bytes = l_BinaryReader.ReadBytes( byteHashCode.Length );

                                if ( bytes.Length == byteHashCode.Length )
                                {
                                    bool bValid = true;

                                    for ( int iIndex = 0; iIndex < bytes.Length; ++iIndex )
                                    {
                                        if ( bytes[iIndex] != byteHashCode[iIndex] )
                                        {
                                            bValid = false;
                                            break;
                                        }
                                    }

                                    if ( bValid )
                                    {
                                        assembly = Assembly.LoadFrom( "Scripts/Scripts.CS.dll" );

                                        if ( !s_AdditionalReferences.Contains( assembly.Location ) )
                                        {
                                            s_AdditionalReferences.Add( assembly.Location );
                                        }

                                        LOGs.WriteLine( LogMessageType.MSG_INFO, "脚本: 完成 C# (读取无任何改变的缓存文件)" );

                                        return true;
                                    }
                                }
                            }
                        }
                    }
                    catch { }
                }
            }

            DeleteFiles( "Scripts.CS*.dll" );

            using ( CSharpCodeProvider l_CSharpCodeProvider = new CSharpCodeProvider() )
            {
                string strPath = GetUnusedPath( "Scripts.CS" );

                CompilerParameters l_CompilerParameters = new CompilerParameters( GetReferenceAssemblies(), strPath, bDebug );

                string strDefines = GetDefines();

                if ( strDefines != null )
                    l_CompilerParameters.CompilerOptions = string.Format( "/D:{0}", strDefines );

                if ( BaseServer.HaltOnWarning == true )
                    l_CompilerParameters.WarningLevel = 4;

                CompilerResults l_CompilerResults = l_CSharpCodeProvider.CompileAssemblyFromFile( l_CompilerParameters, strFiles );
                s_AdditionalReferences.Add( strPath );

                Display( l_CompilerResults );

                if ( l_CompilerResults.Errors.Count > 0 )
                {
                    assembly = null;
                    return false;
                }

                if ( bCache && Path.GetFileName( strPath ) == "Scripts.CS.dll" )
                {
                    try
                    {
                        byte[] byteHashCode = GetHashCode( strPath, strFiles, bDebug );

                        using ( FileStream l_FileStream = new FileStream( "Scripts/Scripts.CS.hash", FileMode.Create, FileAccess.Write, FileShare.None ) )
                        {
                            using ( BinaryWriter l_BinaryWriter = new BinaryWriter( l_FileStream ) )
                            {
                                l_BinaryWriter.Write( byteHashCode, 0, byteHashCode.Length );
                            }
                        }
                    }
                    catch { }
                }

                assembly = l_CompilerResults.CompiledAssembly;
                return true;
            }
        }

        /// <summary>
        /// 编译VB的源码
        /// </summary>
        public static bool CompileVBScripts( out Assembly assembly )
        {
            return CompileVBScripts( false, out assembly );
        }

        /// <summary>
        /// 编译VB的源码
        /// </summary>
        public static bool CompileVBScripts( bool bDebug, out Assembly assembly )
        {
            return CompileVBScripts( bDebug, true, out assembly );
        }

        /// <summary>
        /// 编译VB的源码
        /// </summary>
        public static bool CompileVBScripts( bool bDebug, bool bCache, out Assembly assembly )
        {
            LOGs.WriteLine( LogMessageType.MSG_INFO, "脚本: 开始编译 VB.NET 脚本..." );
            string[] strFiles = GetScripts( "*.vb" );

            if ( strFiles.Length == 0 )
            {
                if ( bCache && File.Exists( "Scripts/Scripts.VB.dll" ) )
                {
                    assembly = Assembly.LoadFrom( "Scripts/Scripts.VB.dll" );

                    if ( !s_AdditionalReferences.Contains( assembly.Location ) )
                    {
                        s_AdditionalReferences.Add( assembly.Location );
                    }

                    LOGs.WriteLine( LogMessageType.MSG_INFO, "脚本: 完成 VB.NET (读取无任何改变的缓存文件)" );

                    return true;
                }
                else
                {
                    LOGs.WriteLine( LogMessageType.MSG_WARNING, "脚本: 没有找到 VB.NET 的脚本文件!" );
                    assembly = null;
                    return true;
                }
            }

            if ( File.Exists( "Scripts/Scripts.VB.dll" ) )
            {
                if ( bCache && File.Exists( "Scripts/Scripts.VB.hash" ) )
                {
                    byte[] hashCode = GetHashCode( "Scripts/Scripts.VB.dll", strFiles, bDebug );

                    try
                    {
                        using ( FileStream l_FileStream = new FileStream( "Scripts/Scripts.VB.hash", FileMode.Open, FileAccess.Read, FileShare.Read ) )
                        {
                            using ( BinaryReader l_BinaryReader = new BinaryReader( l_FileStream ) )
                            {
                                byte[] bytes = l_BinaryReader.ReadBytes( hashCode.Length );

                                if ( bytes.Length == hashCode.Length )
                                {
                                    bool bValid = true;

                                    for ( int iIndex = 0; iIndex < bytes.Length; ++iIndex )
                                    {
                                        if ( bytes[iIndex] != hashCode[iIndex] )
                                        {
                                            bValid = false;
                                            break;
                                        }
                                    }

                                    if ( bValid )
                                    {
                                        assembly = Assembly.LoadFrom( "Scripts/Scripts.VB.dll" );

                                        if ( !s_AdditionalReferences.Contains( assembly.Location ) )
                                        {
                                            s_AdditionalReferences.Add( assembly.Location );
                                        }

                                        LOGs.WriteLine( LogMessageType.MSG_INFO, "脚本: 完成 VB.NET (读取无任何改变的缓存文件)" );

                                        return true;
                                    }
                                }
                            }
                        }
                    }
                    catch
                    {
                    }
                }
            }

            DeleteFiles( "Scripts.VB*.dll" );

            using ( VBCodeProvider provider = new VBCodeProvider() )
            {
                string strPath = GetUnusedPath( "Scripts.VB" );

                CompilerParameters l_CompilerParameters = new CompilerParameters( GetReferenceAssemblies(), strPath, bDebug );

                string strDefines = GetDefines();

                if ( strDefines != null )
                    l_CompilerParameters.CompilerOptions = String.Format( "/D:{0}", strDefines );

                if ( BaseServer.HaltOnWarning == true )
                    l_CompilerParameters.WarningLevel = 4;

                CompilerResults l_CompilerResults = provider.CompileAssemblyFromFile( l_CompilerParameters, strFiles );
                s_AdditionalReferences.Add( strPath );

                Display( l_CompilerResults );

                if ( l_CompilerResults.Errors.Count > 0 )
                {
                    assembly = null;
                    return false;
                }

                if ( bCache && Path.GetFileName( strPath ) == "Scripts.VB.dll" )
                {
                    try
                    {
                        byte[] byteHashCode = GetHashCode( strPath, strFiles, bDebug );

                        using ( FileStream l_FileStream = new FileStream( "Scripts/Scripts.VB.hash", FileMode.Create, FileAccess.Write, FileShare.None ) )
                        {
                            using ( BinaryWriter l_BinaryWriter = new BinaryWriter( l_FileStream ) )
                            {
                                l_BinaryWriter.Write( byteHashCode, 0, byteHashCode.Length );
                            }
                        }
                    }
                    catch { }
                }

                assembly = l_CompilerResults.CompiledAssembly;
                return true;
            }
        }

        /// <summary>
        /// 显示编译后的信息
        /// </summary>
        public static void Display( CompilerResults compilerResults )
        {
            if ( compilerResults.Errors.Count > 0 )
            {
                Dictionary<string, List<CompilerError>> l_DictionaryErrors = new Dictionary<string, List<CompilerError>>( compilerResults.Errors.Count, StringComparer.OrdinalIgnoreCase );
                Dictionary<string, List<CompilerError>> l_DictionaryWarnings = new Dictionary<string, List<CompilerError>>( compilerResults.Errors.Count, StringComparer.OrdinalIgnoreCase );

                foreach ( CompilerError l_CompilerError in compilerResults.Errors )
                {
                    Dictionary<string, List<CompilerError>> l_Table = ( l_CompilerError.IsWarning ? l_DictionaryWarnings : l_DictionaryErrors );

                    List<CompilerError> l_List = null;
                    l_Table.TryGetValue( l_CompilerError.FileName, out l_List );

                    if ( l_List == null )
                        l_Table[l_CompilerError.FileName] = l_List = new List<CompilerError>();

                    l_List.Add( l_CompilerError );
                }

                if ( l_DictionaryErrors.Count > 0 )
                    LOGs.WriteLine( LogMessageType.MSG_FATALERROR, "脚本: 失败 ({0} 错误, {1} 警告)", l_DictionaryErrors.Count, l_DictionaryWarnings.Count );
                else
                    LOGs.WriteLine( LogMessageType.MSG_NOTICE, "脚本: 完成 ({0} 错误, {1} 警告)", l_DictionaryErrors.Count, l_DictionaryWarnings.Count );

                string strScriptRoot = Path.GetFullPath( Path.Combine( BaseServer.BaseDirectory, "../Scripts" + Path.DirectorySeparatorChar ) );
                Uri scriptRootUri = new Uri( strScriptRoot );

                if ( l_DictionaryWarnings.Count > 0 )
                    LOGs.WriteLine( LogMessageType.MSG_WARNING, "警告: " );

                foreach ( KeyValuePair<string, List<CompilerError>> l_KeyValuePair in l_DictionaryWarnings )
                {
                    string strFileName = l_KeyValuePair.Key;
                    List<CompilerError> l_List = l_KeyValuePair.Value;

                    string strFullPath = Path.GetFullPath( strFileName );
                    string strUsedPath = Uri.UnescapeDataString( scriptRootUri.MakeRelativeUri( new Uri( strFullPath ) ).OriginalString );

                    LOGs.WriteLine( LogMessageType.MSG_WARNING, " + {0}:", strUsedPath );

                    foreach ( CompilerError l_CompilerError in l_List )
                        LOGs.WriteLine( LogMessageType.MSG_WARNING, "    {0}: 行 {1}: {3}", l_CompilerError.ErrorNumber, l_CompilerError.Line, l_CompilerError.Column, l_CompilerError.ErrorText );
                }

                if ( l_DictionaryErrors.Count > 0 )
                    LOGs.WriteLine( LogMessageType.MSG_ERROR, "错误: " );

                foreach ( KeyValuePair<string, List<CompilerError>> l_KeyValuePair in l_DictionaryErrors )
                {
                    string strFileName = l_KeyValuePair.Key;
                    List<CompilerError> l_List = l_KeyValuePair.Value;

                    string strFullPath = Path.GetFullPath( strFileName );
                    string strUsedPath = Uri.UnescapeDataString( scriptRootUri.MakeRelativeUri( new Uri( strFullPath ) ).OriginalString );

                    LOGs.WriteLine( LogMessageType.MSG_ERROR, " + {0}:", strUsedPath );

                    foreach ( CompilerError l_CompilerError in l_List )
                        LOGs.WriteLine( LogMessageType.MSG_ERROR, "    {0}: 行 {1}: {3}", l_CompilerError.ErrorNumber, l_CompilerError.Line, l_CompilerError.Column, l_CompilerError.ErrorText );
                }
            }
            else
            {
                LOGs.WriteLine( LogMessageType.MSG_NOTICE, "脚本: 完成 (0 错误, 0 警告)" );
            }
        }

        /// <summary>
        /// 编译默认目录的脚本
        /// </summary>
        public static bool Compile()
        {
            return Compile( false );
        }

        /// <summary>
        /// 编译默认目录的脚本
        /// </summary>
        public static bool Compile( bool bDebug )
        {
            return Compile( bDebug, true );
        }

        /// <summary>
        /// 编译默认目录的脚本
        /// </summary>
        public static bool Compile( bool bDebug, bool bCache )
        {
            EnsureDirectory( "Scripts/" );

            if ( s_AdditionalReferences.Count > 0 )
                s_AdditionalReferences.Clear();

            List<Assembly> l_Assemblies = new List<Assembly>();

            Assembly l_Assembly;

            if ( CompileCSScripts( bDebug, bCache, out l_Assembly ) )
            {
                if ( l_Assembly != null )
                    l_Assemblies.Add( l_Assembly );
            }
            else { return false; }

            if ( CompileVBScripts( bDebug, bCache, out l_Assembly ) )
            {
                if ( l_Assembly != null )
                    l_Assemblies.Add( l_Assembly );
            }
            else { return false; }

            if ( l_Assemblies.Count == 0 )
                return false;

            s_Assemblies = l_Assemblies.ToArray();

            // 以下是调用脚本class里面的静态的Configure方法
            List<MethodInfo> l_InvokeList = new List<MethodInfo>();

            for ( int iIndex = 0; iIndex < s_Assemblies.Length; ++iIndex )
            {
                Type[] l_Types = s_Assemblies[iIndex].GetTypes();

                for ( int iIndex2 = 0; iIndex2 < l_Types.Length; ++iIndex2 )
                {
                    if ( l_Types[iIndex2].GetInterface( "IConfigure", true ) != null )
                    {
                        MethodInfo l_MethodInfo = l_Types[iIndex2].GetMethod( "Configure", BindingFlags.Static | BindingFlags.Public );

                        if ( l_MethodInfo != null )
                            l_InvokeList.Add( l_MethodInfo );
                    }
                }
            }

            l_InvokeList.Sort( new CallPriorityComparer() );

            for ( int iIndex = 0; iIndex < l_InvokeList.Count; ++iIndex )
                l_InvokeList[iIndex].Invoke( null, null );

            l_InvokeList.Clear();

            // 以下是调用脚本class里面的静态的Initialize方法
            for ( int iIndex = 0; iIndex < s_Assemblies.Length; ++iIndex )
            {
                Type[] l_Types = s_Assemblies[iIndex].GetTypes();

                for ( int iIndex2 = 0; iIndex2 < l_Types.Length; ++iIndex2 )
                {
                    if ( l_Types[iIndex2].GetInterface( "IInitialize", true ) != null )
                    {
                        MethodInfo l_MethodInfo = l_Types[iIndex2].GetMethod( "Initialize", BindingFlags.Static | BindingFlags.Public );

                        if ( l_MethodInfo != null )
                            l_InvokeList.Add( l_MethodInfo );
                    }
                }
            }

            l_InvokeList.Sort( new CallPriorityComparer() );

            for ( int iIndex = 0; iIndex < l_InvokeList.Count; ++iIndex )
                l_InvokeList[iIndex].Invoke( null, null );

            return true;
        }

        /// <summary>
        /// 给出的某个程序集的类型申明缓冲的类
        /// </summary>
        public static TypeCache GetTypeCache( Assembly assembly )
        {
            if ( assembly == null )
                return s_NullCache;

            TypeCache l_TypeCache = null;
            s_TypeCaches.TryGetValue( assembly, out l_TypeCache );

            if ( l_TypeCache == null )
                s_TypeCaches[assembly] = l_TypeCache = new TypeCache( assembly );

            return l_TypeCache;
        }

        /// <summary>
        /// 给出全部限定名的类型申明,忽略大小写
        /// </summary>
        public static Type FindTypeByFullName( string strFullName )
        {
            return FindTypeByFullName( strFullName, true );
        }

        /// <summary>
        /// 给出全部限定名的类型申明,是否忽略大小写
        /// </summary>
        public static Type FindTypeByFullName( string strFullName, bool bIgnoreCase )
        {
            Type l_Type = null;

            for ( int iIndex = 0; l_Type == null && iIndex < s_Assemblies.Length; ++iIndex )
                l_Type = GetTypeCache( s_Assemblies[iIndex] ).GetTypeByFullName( strFullName, bIgnoreCase );

            if ( l_Type == null )
                l_Type = GetTypeCache( BaseServer.Assembly ).GetTypeByFullName( strFullName, bIgnoreCase );

            return l_Type;
        }

        /// <summary>
        /// 给出类型申明,忽略大小写
        /// </summary>
        public static Type FindTypeByName( string strName )
        {
            return FindTypeByName( strName, true );
        }

        /// <summary>
        /// 给出类型申明,是否忽略大小写
        /// </summary>
        public static Type FindTypeByName( string strName, bool bIgnoreCase )
        {
            Type l_Type = null;

            for ( int iIndex = 0; l_Type == null && iIndex < s_Assemblies.Length; ++iIndex )
                l_Type = GetTypeCache( s_Assemblies[iIndex] ).GetTypeByName( strName, bIgnoreCase );

            if ( l_Type == null )
                l_Type = GetTypeCache( BaseServer.Assembly ).GetTypeByName( strName, bIgnoreCase );

            return l_Type;
        }

        /// <summary>
        /// 给出目录的全部文件
        /// </summary>
        public static string[] GetScripts( string strFilter )
        {
            List<string> l_List = new List<string>();

            GetScripts( ref l_List, Path.Combine( BaseServer.BaseDirectory, "../Scripts" ), strFilter );

            return l_List.ToArray();
        }
        #endregion

        #region zh-CHS 静态的私有方法 | en Static Private Method
        /// <summary>
        /// 给出定义(用于编译器的附加命令行参数 - /D(定义的一个或多个符号的名称))
        /// </summary>
        private static string GetDefines()
        {
            StringBuilder l_StringBuilder = new StringBuilder();

            // These two defines are legacy, ie, depreciated.
            if ( BaseServer.Is64Bit )
                AppendDefine( ref l_StringBuilder, "x64" );

            AppendDefine( ref l_StringBuilder, "Framework_2_0" );

            return l_StringBuilder.ToString();
        }

        /// <summary>
        /// 添加定义(用于编译器的附加命令行参数 - /D(定义的一个或多个符号的名称))
        /// </summary>
        private static void AppendDefine( ref StringBuilder stringBuilder, string strDefine )
        {
            stringBuilder.Append( strDefine );
            stringBuilder.Append( ';' );
        }

        /// <summary>
        /// 给出某个文件的SHA1的Hash值(计算脚本文件的时间来得到Hash值)
        /// </summary>
        private static byte[] GetHashCode( string strCompiledFile, string[] strScriptFiles, bool bDebug )
        {
            using ( MemoryStream l_MemoryStream = new MemoryStream() )
            {
                using ( BinaryWriter l_BinaryWriter = new BinaryWriter( l_MemoryStream ) )
                {
                    FileInfo l_FileInfo = new FileInfo( strCompiledFile );

                    l_BinaryWriter.Write( l_FileInfo.LastWriteTimeUtc.Ticks );

                    foreach ( string strScriptFile in strScriptFiles )
                    {
                        l_FileInfo = new FileInfo( strScriptFile );

                        l_BinaryWriter.Write( l_FileInfo.LastWriteTimeUtc.Ticks );
                    }

                    l_BinaryWriter.Write( bDebug );

                    l_MemoryStream.Position = 0;

                    using ( SHA1 l_Sha1 = SHA1.Create() )
                    {
                        return l_Sha1.ComputeHash( l_MemoryStream );
                    }
                }
            }
        }

        /// <summary>
        /// 给出目录唯一的路径文件的名称
        /// </summary>
        private static string GetUnusedPath( string strName )
        {
            string strPath = Path.Combine( BaseServer.BaseDirectory, String.Format( "Scripts/{0}.dll", strName ) );

            for ( int iIndex = 2; File.Exists( strPath ) && iIndex <= 1000; ++iIndex )
                strPath = Path.Combine( BaseServer.BaseDirectory, String.Format( "Scripts/{0}.{1}.dll", strName, iIndex ) );

            return strPath;
        }

        /// <summary>
        /// 删除目录里面的文件
        /// </summary>
        private static void DeleteFiles( string strMask )
        {
            try
            {
                string[] strFiles = Directory.GetFiles( Path.Combine( BaseServer.BaseDirectory, "Scripts" ), strMask );

                foreach ( string strFile in strFiles )
                {
                    try { File.Delete( strFile ); }
                    catch { }
                }
            }
            catch { }
        }

        /// <summary>
        /// 确保目录的存在
        /// </summary>
        private static void EnsureDirectory( string strDir )
        {
            string strPath = Path.Combine( BaseServer.BaseDirectory, strDir );

            if ( Directory.Exists( strPath ) == false )
                Directory.CreateDirectory( strPath );
        }

        /// <summary>
        /// 给出目录的全部文件
        /// </summary>
        private static void GetScripts( ref List<string> listString, string strPath, string strFilter )
        {
            foreach ( string strDir in Directory.GetDirectories( strPath ) )
                GetScripts( ref listString, strDir, strFilter );

            listString.AddRange( Directory.GetFiles( strPath, strFilter ) );
        }
        #endregion
    }
}
#endregion

